package com.iwhalecloud.bss.kite.cucc.web.service.accept.handler.attr;

import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.vo.scene.CommonAttrVO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.flow.IFlowService;
import com.iwhalecloud.bss.kite.cucc.client.api.order.IOrderService;
import com.iwhalecloud.bss.kite.cucc.client.dto.flow.FlowTrackInfo;
import com.iwhalecloud.bss.kite.cucc.client.dto.flow.FlowTrackReq;
import com.iwhalecloud.bss.kite.cucc.client.dto.order.OrderInfo;
import com.iwhalecloud.bss.kite.cucc.client.dto.order.OrderInfoListReq;
import com.iwhalecloud.bss.kite.cucc.client.dto.order.OrderInfoReq;
import com.iwhalecloud.bss.kite.cucc.client.dto.order.OrderListInfo;
import com.iwhalecloud.bss.kite.cucc.common.util.CommonUtil;
import com.iwhalecloud.bss.kite.cucc.common.util.DateFormatUtils;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.web.service.accept.attr.handler.AbstractAttrHandler;
import com.ztesoft.bss.common.exception.BssException;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.List;
import java.util.Map;


/**
 * @Classname RentStopTimeSdwanHandler
 * @Description SDWAN 止租时间限制规则
 *     1.预销户：如起租和拆机不是同一个月，则拆机报竣时间前个月月底最后一天 < 止租时间选择范围 < 拆机报竣时间
 *             如起租和拆机是同一个月，则起租时间 < 止租时间选择范围 < 拆机报竣时间
 *     2.停机：手动止租时止租时间有选择限制：停机报竣时间前个月月底最后一天 < 止租时间选择范围 < 停机报竣时间
 * @Author zhang.song
 * @Date 2021-04-21 20:57
 */
@Service
public class RentStopTimeSdwanHandler extends AbstractAttrHandler {

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private IFlowService flowService;

    @Autowired
    private IOrderService orderService;

    @Override
    public void init(CommonAttrVO commonAttr) {

    }

    @Override
    public DataResult<Boolean> apply(String sceneInstId, String fieldName, String value, String valueDesc) {
        LocalDate targetDate = stringToDate(value);
        if(targetDate != null) {
            String orderId = querySceneInstService.getExtParameterValue(sceneInstId, "orderId");
            // 拆机、停机报竣时间
            LocalDate endDate = this.getFinishDate(orderId, "OrderOpenSDWAN");
            if(endDate != null) {
                KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
                String serviceOfferId = sceneInst.getServiceOfferId();
                if(KiteStringUtils.isEqual(serviceOfferId, "1005")) {
                    // 预销户
                    String serialNumber = querySceneInstService.getCommonAttrValue(sceneInstId, "business_number");
                    String goodOrderId = this.getGoodOrderId(sceneInstId, serialNumber);
                    // 起租完成时间
                    LocalDate startRentDate = this.getFinishDate(goodOrderId, "OrderStartRent");

                    if(startRentDate != null) {
                        String startDateType = "起租时间";
                        // 起租和拆机不是同一个月，止租时间 > 拆机报竣时间前个月月底最后一天，否则，止租时间 > 起租时间
                        if(startRentDate.getMonthValue() != endDate.getMonthValue()) {
                            startRentDate = endDate.with(TemporalAdjusters.firstDayOfMonth()).plusDays(-1);
                            startDateType = "拆机报竣时间前个月月底最后一天";
                        }
                        if(!targetDate.isAfter(startRentDate)) {
                            BssException.throwOut("", "", "止租时间必须大于" + startDateType + "（" + startRentDate.toString() + "）");
                        }
                    }
                    if(endDate.isBefore(targetDate)) {
                        BssException.throwOut("", "", "止租时间不能大于拆机报竣时间（" + endDate.toString() + "）");
                    }
                } else if(KiteStringUtils.isEqual(serviceOfferId, "1003")) {
                    // 停机
                    LocalDate startDate = endDate.with(TemporalAdjusters.firstDayOfMonth()).plusDays(-1);
                    if(!targetDate.isAfter(startDate)) {
                        BssException.throwOut("", "", "止租时间必须大于停机报竣时间前个月月底最后一天（" + startDate.toString() + "）");
                    }
                    if(endDate.isBefore(targetDate)) {
                        BssException.throwOut("", "", "止租时间不能大于停机报竣时间（" + endDate.toString() + "）");
                    }
                }
            }

        }
        return super.apply(sceneInstId, fieldName, value, valueDesc);
    }

    /**
     * 查询业务销户（拆机报竣时间、停机报竣时间）环节完成时间
     * @author zhang.song
     * @date 2021-04-21 21:02
     * @param orderId
     * @param tacheCode
     * @return java.time.LocalDate
     */
    private LocalDate getFinishDate(String orderId, String tacheCode) {
        LocalDate localDate = null;
        FlowTrackReq flowTrackReq = new FlowTrackReq();
        flowTrackReq.setOrderId(orderId);
        FlowTrackInfo flowTrackInfo = flowService.getFlowTrack(flowTrackReq);
        if(KiteStringUtils.isEqual(flowTrackInfo.getCode(), "00000")) {
            Map<String, Object> flowData = flowTrackInfo.getFlowData();
            List<Map<String, Object>> flow = CommonUtil.getList(flowData, "FLOW");
            if(flow != null && flow.size() > 0) {
                List<Map<String, Object>> flowList = CommonUtil.getList(flow.get(0), "FLOW_DATA");
                if(flowList != null && flowList.size() > 0) {
                    for (Map<String, Object> flowMap : flowList) {
                        if(KiteStringUtils.isEqual(MapUtils.getString(flowMap, "MODULE_CODE"), tacheCode)) {
                            // 业务销户 环节完成时间（拆机报竣时间、停机报竣时间）
                            localDate = stringToDate(MapUtils.getString(flowMap, "FINISH_DT"));
                            break;
                        }
                    }
                }
            }
        }
        return localDate;
    }

    /**
     * 查商品订购流程的orderId
     * @author zhang.song
     * @date 2021-04-21 21:53
     * @param sceneInstId
     * @param serialNumber
     * @return java.lang.String
     */
    private String getGoodOrderId(String sceneInstId, String serialNumber) {
        if(KiteStringUtils.isEmpty(serialNumber)) {
            return null;
        }
        OrderInfoListReq orderInfoListReq = new OrderInfoListReq();
        orderInfoListReq.setQueryType("order");
        orderInfoListReq.setPage("1");
        orderInfoListReq.setSize("1");
        OrderInfoReq order = new OrderInfoReq();
        order.setSerialNumber(serialNumber);
        order.setBizType("1001");
        order.setStatus("1");
        order.setOrderId(querySceneInstService.getExtParameterValue(sceneInstId, "outOrderId"));
        orderInfoListReq.setOrder(order);
        OrderListInfo orderListInfo = orderService.queryOrderList(orderInfoListReq);
        if(orderListInfo == null || !KiteStringUtils.equals(orderListInfo.getCode(), "00000")) {
            return null;
        }
        List<OrderInfo> orderInfoList = orderListInfo.getOrderInfoList();
        if(KiteListUtils.isEmpty(orderInfoList)) {
            return null;
        }
        return orderInfoList.get(0).getOrderId();
    }

    /**
     * 字符串转时间（yyyy-MM-dd）
     * @author zhang.song
     * @date 2021-04-22 14:58
     * @param value
     * @return java.time.LocalDate
     */
    private static LocalDate stringToDate(String value) {
        if(KiteStringUtils.isEmpty(value)) {
            return null;
        }
        if(value.length() > DateFormatUtils.DATE_FORMAT.length()) {
            value = value.substring(0, DateFormatUtils.DATE_FORMAT.length());
        }
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DateFormatUtils.DATE_FORMAT);
        LocalDate localDate = null;
        try {
            localDate = LocalDate.parse(value, dtf);
        } catch (Exception e) {
            ErrorConsts.BUSI_COMMON_ERROR.throwOut("日期转换异常");
        }
        return localDate;
    }
}
